package com.example.demo.service;

import com.alibaba.fastjson2.JSON;
import com.example.demo.config.AliyunConfig;
import com.example.demo.config.RabbitMQConfig;
import com.example.demo.model.dto.SingleCallByTtsRequestDTO;
import com.example.demo.model.message.AlarmNotificationMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

@Service
@Slf4j
public class AlarmNotificationService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private DyvmsService dyvmsService;

    @Autowired
    private AliyunConfig aliyunConfig;

    // 添加时间单位转换常量
    private static final int MINUTES_TO_MILLISECONDS = 60 * 1000;

    private SingleCallByTtsRequestDTO buildAlarmCallRequest(String deviceName, String alarmType, String phoneNumber) {
        String displayName = deviceName;
        if (deviceName.matches("\\d+") && deviceName.length() >= 4) {
            displayName = deviceName.substring(deviceName.length() - 4);
        }

        return SingleCallByTtsRequestDTO.builder()
                .calledNumber(phoneNumber)
                .calledShowNumber(aliyunConfig.getDyvms().getCalledShowNumber())
                .ttsCode(aliyunConfig.getDyvms().getTtsCode())
                .build();
    }

    public void scheduleAlarmNotifications(String deviceName, String alarmType,
                                           String phoneNumber, int maxAttempts, int intervalMinutes) {
        // 记录首次报警时间和配置信息
        AlarmNotificationMessage message = new AlarmNotificationMessage();
        message.setDeviceName(deviceName);
        message.setAlarmType(alarmType);
        message.setPhoneNumber(phoneNumber);
        message.setCurrentAttempt(1);
        message.setMaxAttempts(maxAttempts);
        message.setIntervalSeconds(intervalMinutes); // 存储时仍使用原始值，方便日志记录
        message.setFirstAlarmTime(LocalDateTime.now());

        // 发送第一条消息（不延迟）
        rabbitTemplate.convertAndSend(
                RabbitMQConfig.EXCHANGE_NAME,
                RabbitMQConfig.ROUTING_KEY,
                JSON.toJSONString(message)
        );

        log.info("安排首次电话报警通知，设备：{}，报警类型：{}，间隔时间：{}分钟，最大尝试次数：{}",
                deviceName, alarmType, intervalMinutes, maxAttempts);
    }

    public void scheduleBatchAlarmNotifications(String deviceName, String alarmType,
                                                List<String> phoneNumbers, int maxAttempts, int intervalMinutes) {
        // 对所有手机号发送第一次通知
        for (String phone : phoneNumbers) {
            scheduleAlarmNotifications(deviceName, alarmType, phone, maxAttempts, intervalMinutes);
        }
    }

    @RabbitListener(queues = RabbitMQConfig.QUEUE_NAME)
    public void handleAlarmNotification(String messageJson) {
        try {
            AlarmNotificationMessage message = JSON.parseObject(messageJson, AlarmNotificationMessage.class);

            // 检查是否超过最大通知时间(24小时)
            if (ChronoUnit.HOURS.between(message.getFirstAlarmTime(), LocalDateTime.now()) >= 24) {
                log.warn("设备[{}]报警通知超过24小时，停止通知", message.getDeviceName());
                return;
            }

            // 执行电话通知
            SingleCallByTtsRequestDTO callRequest = buildAlarmCallRequest(
                    message.getDeviceName(), message.getAlarmType(), message.getPhoneNumber());
            String response = dyvmsService.singleCallByTts(callRequest);

            log.info("第{}次电话报警通知发送成功，设备：{}，报警类型：{}，手机号：{}，响应：{}",
                    message.getCurrentAttempt(), message.getDeviceName(),
                    message.getAlarmType(), message.getPhoneNumber(), response);

            // 如果还需要继续通知
            if (message.getCurrentAttempt() < message.getMaxAttempts()) {
                message.setCurrentAttempt(message.getCurrentAttempt() + 1);

                // 将interval从分钟转换为毫秒
                int delayMilliseconds = message.getIntervalSeconds() * MINUTES_TO_MILLISECONDS;

                // 构建延迟消息
                Message delayedMessage = MessageBuilder
                        .withBody(JSON.toJSONString(message).getBytes())
                        .setHeader("x-delay", delayMilliseconds)
                        .build();

                // 发送延迟消息
                rabbitTemplate.convertAndSend(
                        RabbitMQConfig.EXCHANGE_NAME,
                        RabbitMQConfig.ROUTING_KEY,
                        delayedMessage
                );

                log.info("安排下一次电话报警通知，设备：{}，当前尝试次数：{}/{}，延迟：{}分钟",
                        message.getDeviceName(), message.getCurrentAttempt(),
                        message.getMaxAttempts(), message.getIntervalSeconds());
            }
        } catch (Exception e) {
            log.error("处理报警通知失败", e);
            throw new AmqpRejectAndDontRequeueException(e);
        }
    }
}